package com.meme.editor.gui;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.JPanel;
import javax.swing.JList;
import javax.swing.JToolBar;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;

import javax.swing.JScrollPane;

import org.apache.log4j.Logger;

import com.meme.app.ResourceManager;
//import com.meme.editor.ObjectWithProperties;
import com.meme.editor.event.EntityChangedEvent;
import com.meme.editor.event.EntityObjectListener;
import com.meme.editor.gui.sprite2d.Sprite2dMainPanel;
import com.meme.editor.model.sprite2d.Sprite2dFile;
import com.meme.editor.EntityObject;

import javax.swing.ListCellRenderer;


public class EntityChildrenListView extends JPanel 
	implements EntityObjectListener, AncestorListener, ListSelectionListener
{
	static Logger logger = Logger.getLogger (EntityChildrenListView.class);
	
	
	EntityObject mEntity;
	PropertyEditPanel mPropertyEditPanel;
	EntityChildrenListView mGrandChildrenView;
	
	JScrollPane mScrollPane;
	JPanel mRootPanel;
	JList mList;
	JToolBar mToolbar;
	
	public EntityChildrenListView ()
	{
		this (null, true, true, true);
	}
	
	public EntityChildrenListView (EntityObject entity)
	{
		this (entity, true, true, true);
	}

	public EntityChildrenListView (EntityObject entity, boolean canInsert, boolean canRemove, boolean canSwap)
	{
		mList = new JList ();
		mList.addListSelectionListener (this);

		setEntity (entity);		
		
		addAncestorListener (this);
		
		
		
		mScrollPane = new JScrollPane (mList);
		
		mToolbar = new JToolBar ();  
		mToolbar.setFloatable (false);
		mToolbar.setBorderPainted ( true );
		mToolbar.setRollover ( true );
		if (canInsert)
		{
			mToolbar.add (new NewChildAction (ResourceManager.getIcon("add")));
			mToolbar.add (new InsertChildAction (ResourceManager.getIcon("insert")));
		}
		if (canRemove)
			mToolbar.add (new DeleteChildAction (ResourceManager.getIcon("delete")));
		if (canSwap)
		{
			mToolbar.add (new MoveUpChildAction (ResourceManager.getIcon("up")));
			mToolbar.add (new MoveDownChildAction (ResourceManager.getIcon("down")));
		}
		
		setLayout ( new BorderLayout() );
		add (mToolbar, BorderLayout.NORTH);
		add (mScrollPane, BorderLayout.CENTER);
	}
	
	public JList getListComponent ()
	{
		return mList;
	}
	
	
	public void setSelectedIndex (int index)
	{
		if ( mEntity != null && index >= 0 && index < mEntity.getChildrenCount() )
			mList.setSelectedIndex(index);
	}
	
	public void setEntity (EntityObject entity)
	{
		if (mEntity != null)
		{
			mEntity.removeEntityObjectListener (this);	
		}
		
		mEntity = entity;
		
		if ( mEntity != null )
		{
			if ( mPropertyEditPanel != null && mEntity.getChildrenCount() == 0 )
				mPropertyEditPanel.setDataSource (null);
			
			mList.setListData(mEntity.getChildren());
			
			mEntity.addEntityObjectListener (this);	
			
			repaint ();
		}
	}
	
	public EntityObject getEntity ()
	{
		return mEntity;
	}
	
	public void setPropertyEditPanel (PropertyEditPanel  propertyEditPanel)
	{
		mPropertyEditPanel = propertyEditPanel;
	}
	
	public void setGrandChildrenView (EntityChildrenListView grandChildrenView)
	{
		mGrandChildrenView = grandChildrenView;
	}
	
	// AncestorListener
	@Override
	public void ancestorAdded(AncestorEvent event) 
	{
		if ( mEntity != null )
			mEntity.addEntityObjectListener (this);		
	}

	@Override
	public void ancestorRemoved(AncestorEvent event)  
	{
		if ( mEntity != null )
			mEntity.removeEntityObjectListener (this);	
	}
	
	@Override
	public void ancestorMoved(AncestorEvent event) 
	{
		
	}

	
	// PropertyManagerListener
	@Override 
	public void notifyEntityChanged (EntityChangedEvent event)
	{
		logger.assertLog(mEntity == event.getSource(), "Somewhere is wrong.");
		
		if ( ! ( event.isChildrenNamesModifiedEvent() 
				|| event.isChildrenListChangedEvent () ) )
			return;
		
		if ( mEntity != null )
		{
			int index1 = mList.getMinSelectionIndex ();
			if (index1 >= mEntity.getChildrenCount())
				index1 = mEntity.getChildrenCount() - 1;
			if  (index1 < 0)
				index1 = 0;
			mList.setListData(mEntity.getChildren());		
			mList.setSelectedIndex(index1);
			//mList.updateUI ();
		}
		
		valueChanged (null);
		
		repaint ();
	}

	
	// ListSelectionListener
	@Override 
	public void valueChanged(ListSelectionEvent e) 
	{
		int index = mList.getSelectedIndex ();
		if (index >= 0)
		{
			if ( mPropertyEditPanel != null )
				mPropertyEditPanel.setDataSource( mEntity.getChildByIndex ( index ) );
			
			if ( mGrandChildrenView != null )
			{
				mGrandChildrenView.setEntity( mEntity.getChildByIndex ( index ) );
				mGrandChildrenView.setSelectedIndex (0);
			}
		}
	}

	
//----------------------------------------------------------------------------------------
// actions
//----------------------------------------------------------------------------------------
	
	
	class NewChildAction extends AbstractAction 
	{
		public NewChildAction (Icon icon)
		{
			super ("New", icon);
		}
		
	    public void actionPerformed(ActionEvent e) 
	    {
	    	if ( mEntity == null )
	    		return;
	    	
	    	mEntity.addNewChild();
	    	
	    	mList.setSelectedIndex(mEntity.getChildrenCount() - 1);
	    	
	    	mEntity.commitModifications();
	    }
	}
	
	class InsertChildAction extends AbstractAction 
	{
		public InsertChildAction (Icon icon)
		{
			super ("Insert", icon);
		}
		
	    public void actionPerformed(ActionEvent e) 
	    {
	    	if ( mEntity == null )
	    		return;

	    	int index = mList.getSelectedIndex ();
	    	if ( index >= 0 )
	    	{
	    		mEntity.insertNewChild (index);
	    		
	    		mEntity.commitModifications();
	    	}
	    }
	}

	class DeleteChildAction extends AbstractAction 
	{
		public DeleteChildAction (Icon icon)
		{
			super ("Del", icon);
		}
		
	    public void actionPerformed(ActionEvent e) 
	    {
	    	if ( mEntity == null )
	    		return;

	    	int index = mList.getSelectedIndex ();
	    	if ( index >= 0 )
	    		mEntity.removeChild (index);
	    	
	    	if ( index >= mEntity.getChildrenCount() )
	    		mList.setSelectedIndex(mEntity.getChildrenCount() - 1);
	    	
	    	mEntity.commitModifications();
	    }
	}
	
	class MoveUpChildAction extends AbstractAction 
	{
		public MoveUpChildAction (Icon icon)
		{
			super ("Up", icon);
		}
		
	    public void actionPerformed(ActionEvent e) 
	    {
	    	if ( mEntity == null )
	    		return;

	    	int index = mList.getSelectedIndex ();
	    	if ( index > 0 )
	    	{
	    		mEntity.swapChildren(index, index - 1);
	    		mList.setSelectedIndex (index - 1);
	    	}
	    	
	    	mEntity.commitModifications();
	    }
	}

	class MoveDownChildAction extends AbstractAction 
	{
		public MoveDownChildAction (Icon icon)
		{
			super ("Down", icon);
		}
		
	    public void actionPerformed(ActionEvent e) 
	    {
	    	if ( mEntity == null )
	    		return;

	    	int index = mList.getSelectedIndex ();
	    	if ( index >= 0 && index < mEntity.getChildrenCount() - 1 )
	    	{
	    		mEntity.swapChildren(index, index + 1);
	    		mList.setSelectedIndex (index + 1);
	    	}
	    	
	    	mEntity.commitModifications();
	    }
	}

}
